﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Jzy.Workflow.Flow;

using System.Xml.Linq;
using Jzy.Workflow.Node;
using Jzy.Workflow.Task;


using Jzy.Workflow.Form;

using System.Text;

using System.Data;
using Jzy.Workflow.Snap;
using Frame.Lib.Data;
using Frame.Lib.Common;
using Frame.Lib.Web;
using Frame.Lib.Utilities;
using Frame.Lib.Core.Dict;
using Frame.Lib.Enums;
using Frame.Lib.Core.User;
using Frame.Lib.Core.Attach;
using Jzy.DAL;
using Jzy.Workflow;


namespace Jzy.Web.WorkFlow.Fore
{
    public partial class DoForm : PageBase
    {
        private string FlowID
        {
            get
            {
                return Request["FlowID"];
            }
        }

      
        /// <summary>
        /// 不为空即为审批，为空就是新增
        /// </summary>
        private string TaskID//有可能要加密
        {
            get
            {
                return Request["TaskID"];
            }
        }


        private DBHelper _db;
        private DBHelper DbOper
        {
            get
            {
                if (_db == null)
                {
                    _db = DBHelper.Instance();
                }
                return _db;
            }
        }
        

        private FlowBO _flow = new FlowBO();
        private FlowInfo _flowInfo;
        private FlowInfo FlowInfo
        {
            get
            {
                if (_flowInfo == null)
                {
                    _flowInfo = _flow.GetInfo(FlowID);
                }
                return _flowInfo;
            }
        }


        private FlowFormBO _form;
        private FlowFormBO FlowForm
        {
            get
            {
                if (_form == null)
                {
                    _form = new FlowFormBO(DbOper);
                }
                return _form;
            }
        }
        private FlowFormInfo _formInfo;
        private FlowFormInfo FormInfo
        {
            get
            {
                if (_formInfo == null)
                {
                    _formInfo = (this.TaskInfo == null) ? new FlowFormInfo() : this.TaskInfo.FormInfo;
                }
                return _formInfo;
            }
            set
            {
                _formInfo = value;
            }
        }

        private FlowTaskBO _task;
        private FlowTaskBO Task
        {
            get
            {
                if (_task == null)
                {
                    _task = new FlowTaskBO(this.DbOper);
                }
                return _task;
            }
        }
        private FlowTaskInfo _taskInfo;
        private FlowTaskInfo TaskInfo
        {
            get
            {
                if (_taskInfo == null)
                {
                    if (!string.IsNullOrEmpty(TaskID))
                    {
                        _taskInfo = Task.GetInfo(TaskID);
                    }
                }
                return _taskInfo;
            }
            set
            {
                _taskInfo = value;
            }
        }

        /// <summary>
        /// 这个任务是怎么过来的
        /// </summary>
        protected FromType TaskFromType
        {
            get
            {
                if (TaskInfo == null)
                {
                    return FromType.新建;
                }
                else
                {
                    return (FromType)TaskInfo.FromType;
                }
            }
        }

        protected bool AddRight //是否加上权限控制，如果当前用户是申请人就不用权限了（有可能是退回来的）
        {
            get
            {
                return (AppSession.UserID != this.FormInfo.CreatorID);
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {

            CssFileManager.AddCssFile(CssFile.tab1);
            if (!IsPostBack)
            {
                InitData();
            }
            JSUtil.SetDivHeight("divMain", 88);
           
            this.Form.Attributes.Add("enctype", "multipart/form-data");
            //flowPath.InitParameters = "WebAppUrl=" + GlobalVar.WebAppUrl + ",ReadOnly=true";
        }

        private void InitData()
        {           
            
            if (TaskFromType == FromType.传阅)//是否传阅过来的
            {
                btnSend.Value = "已阅";                
            }
            else
            {
                btnSend.Value = "发送";               

                string url =  GlobalVar.WebCurrPath + "Send.aspx?hidSend=" + hidSend.ClientID + "&hidAddSign=" + hidAddSign.ClientID + "&hidPassRound=" + hidPassRound.ClientID + "&hidNextNode=" + hidNextNode.ClientID + "&btnTransfer=" + btnTransfer.ClientID + "&FlowID=" + FlowID + "&TaskID=" + TaskID;
                btnSend.Attributes.Add("onclick", "showForm('" + url + "')");
                //JSUtil.ShowForm(btnSend, "提交表单", null, url, 350, 271);
                if (TaskFromType == FromType.加签)//是否加签过来的
                {
                    JSUtil.ClickBtn(btnSend, btnTransfer);
                }
            }

            if (TaskFromType == FromType.流转 || TaskFromType == FromType.退回)
            {
                btnReturn.Visible = true;
            }
            else
            {
                btnReturn.Visible = false;
            }

            if (TaskFromType == FromType.新建 || AddRight == false)//有可能是退回到拟稿人手里的
            {
                divResult.Visible = false;
               
            }
            else
            {
                btnSave.Text = "暂存";
                DictBO dict = new DictBO();//初始化常用意见
                IEnumerable<DictInfo> dicts = dict.GetList(DictItem.常用意见);
                lv.DataSource = dicts;
                lv.DataBind();    
            
                txtResult.Text = this.TaskInfo.Result;

                if (TaskInfo.ReadTime == null)//初次阅读时间
                {
                    TaskInfo.ReadTime = DateTime.Now;
                    Task.Save(TaskInfo);
                }              
            }

            this.Attachs1.InitData();

            List<EnumInfo> list = ConvertUtil.ConvertEnum(typeof(FormTab));
            if (TaskFromType != FromType.新建)//对附件选项卡进行处理
            {
                list.Where(e => e.ID == (int)FormTab.相关附件).First().Name += "<span style='color:Red;font-weight:bold;'>&nbsp;(" + Attachs1.AttachCount + ")</span>";
            }
            rpt.DataSource = list;
            rpt.DataBind();
                    
            XElement html = null;
            if (this.TaskInfo == null)
            {
                html = XElement.Parse(this.FlowInfo.FormTemplate);
            }
            else
            {
                html = XElement.Parse(this.FormInfo.SnapInfo.FormTemplate);
            }
            litHead.Text = html.Element(ElementItem.Head).Value;
            litForm.Text = html.Element(ElementItem.Body).Value;
          
            InitFormBasicSet(html); 
            InitFormRight();

            this.InitFormData();
           
        }

        /// <summary>
        ///  初始化表单数据
        /// </summary>
        /// <param name="info"></param>
        private void InitFormData()
        {
            string script = null;//向客户端输入的JSON脚本
            if (this.TaskInfo != null)//如是不是新建，或从草稿箱中过来，则还原数据
            {
                StringBuilder sbFormData = new StringBuilder();
                sbFormData.Append("formData = [");
                XElement formData = XElement.Parse(this.TaskInfo.FormInfo.FormData);//表单数据
                foreach (XElement fld in formData.Elements())//对数据内容的过滤暂未处理
                {
                    sbFormData.Append("{name:'" + fld.Name.LocalName + "',type:'" + fld.Attribute("type").Value + "',value:'" + fld.Value.Replace("'", "\\'").Replace("\"", "\\\"") + "'},");
                }
                script = sbFormData.ToString().TrimEnd(',') + "];initData();";
                JSUtil.ExcuteJS(script, "formData");
            }
        }

        /// <summary>
        /// 初始化基本设置 
        /// </summary>
        /// <param name="html"></param>
        private void InitFormBasicSet(XElement html)
        {
            string script = null;
            StringBuilder sbBasicSet = new StringBuilder();
            XElement fields = html.Element(ElementItem.DataFields);
            sbBasicSet.Append("basicSet = [");
            foreach (XElement fld in fields.Elements())
            {
                if (fld.Element(BasicSetItem.MaxLength) != null)//只要有一个存在，那就都会有数据
                {
                    sbBasicSet.Append("{");
                    sbBasicSet.Append("name:'" + fld.Name.LocalName + "',");
                    sbBasicSet.Append("type:'" + fld.Attribute(BasicSetItem.Type).Value + "'");
                    foreach (XElement set in fld.Elements())
                    {
                        string value = set.Value.Replace("'", "\\'").Replace("\"", "\\\"");
                        if (set.Name.LocalName == "Regular")
                        {
                            value = value.Replace("\\", "\\\\");//用于正则表达式
                        }

                        sbBasicSet.Append("," + set.Name.LocalName + ":'" + value + "'");
                    }
                    sbBasicSet.Append("},");
                }
            }

            script = sbBasicSet.ToString().TrimEnd(',') + "];initSet();";
            JSUtil.ExcuteJS(script, "basicSet");

        }

        /// <summary>
        /// 初始化权限
        /// </summary>
        private void InitFormRight()
        {
            string script = null;
            ControlRightBO right = new ControlRightBO();
            int currentNodeID;
            if (this.TaskFromType == FromType.新建)
            {
                currentNodeID = _flow.GetInfo(FlowID).StartNode.ID;
            }
            else
            {
                currentNodeID = this.TaskInfo.ReceiveNodeID;
            }

            //可编辑的控件，默认为不可编辑
            List<string> editCtls = right.GetControls(currentNodeID, AppSession.UserID, RightName.可编辑);
            StringBuilder sbEditCtls = new StringBuilder();
            sbEditCtls.Append("editCtls = [");
            foreach (string ctl in editCtls)
            {
                sbEditCtls.Append("'" + ctl + "',");
            }
            script = sbEditCtls.ToString().TrimEnd(',') + "];";
            JSUtil.ExcuteJS(script, "editCtls");

            //不可见的控件，默认为可见
            List<string> invisibleCtls = right.GetControls(currentNodeID, AppSession.UserID, RightName.不可见);
            StringBuilder sbInvisibleCtls = new StringBuilder();
            sbInvisibleCtls.Append("invisibleCtls = [");
            foreach (string ctl in invisibleCtls)
            {
                sbInvisibleCtls.Append("'" + ctl + "',");
            }
            script = sbInvisibleCtls.ToString().TrimEnd(',') + "];initRight();";
            JSUtil.ExcuteJS(script, "invisibleCtls");

        }

        //发送、加签、传阅
        protected void btnTransfer_Click(object sender, EventArgs e)
        {

            try
            {
                this.DbOper.BeginTrans();
                //如果操作方是被传阅的或是被加签过来的，则直接修改任务状态，不产生新的任务

                //1、保存表单数据及修改本任务状态，并保存审批意见                  
                SaveFormData(TaskState.已完成);

                //2、保存附件
                AttachBO attach = new AttachBO(WFTableName.FlowFormAttach, DbOper);
                attach.Save(Request.Files, this.FormInfo.ID);

                //3、产生新的任务,要根据当前节点是否允许并行来进行判断

                if (TaskFromType != FromType.传阅 && TaskFromType != FromType.加签)
                {
                    bool isCreateNewTask = true;//是否产生新的任务,有时间要写一个存储过程来实现
                    if (this.TaskInfo.ReceiveNodeInfo.IsParallel)//允许并行
                    {
                        if (this.TaskInfo.ReceiveNodeInfo.ParallelMode == (int)ParallelMode.逻辑与)//未考虑并发细节，有可能会出问题
                        {
                            foreach (FlowTaskInfo info in this.TaskInfo.PreTaskInfo.NextTaskInfos)
                            {
                                if (info.ID != this.TaskInfo.ID && info.FromType == (int)FromType.流转 && info.State != (int)TaskState.已完成)//除自己外所有的流转任务需要都完成才能产生新的任务
                                {
                                    isCreateNewTask = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            foreach (FlowTaskInfo info in this.TaskInfo.PreTaskInfo.NextTaskInfos)
                            {
                                if (info.ID != this.TaskInfo.ID)//排除自己
                                {
                                    if (info.FromType == (int)FromType.流转 && info.State == (int)TaskState.已完成)//只要有一个完成了就不再产生新的任务
                                    {
                                        isCreateNewTask = false;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (isCreateNewTask)
                    {
                        List<int> lstSendIDs = StrUtil.SplitToInt(hidSend.Value);
                        int nextNodeID = int.Parse(hidNextNode.Value);
                        CreateNewTask(lstSendIDs,nextNodeID, FromType.流转);

                        List<int> lstAddSignIDs = StrUtil.SplitToInt(hidAddSign.Value);
                        CreateNewTask(lstAddSignIDs, nextNodeID, FromType.加签);

                        List<int> lstPassIDs = StrUtil.SplitToInt(hidPassRound.Value);
                        CreateNewTask(lstPassIDs, nextNodeID, FromType.传阅);

                         //4、判断下一节点是不是结束结节，如是，则整个流程结束
                        FlowNodeInfo nextNode = this.TaskInfo.ReceiveNodeInfo.NextNodes.Where(T => T.ID.ToString() == hidNextNode.Value).First();
                        if(nextNode.TypeID == (int)FlowNodeType.结束)
                        {
                            this.FormInfo.State = (int)FormState.已结束;
                            FlowForm.Save(this.FormInfo);

                            //保存结束的任务

                            FlowTaskInfo info = new FlowTaskInfo();

                            info.FlowID = int.Parse(this.FlowID);
                            info.ReceiveNodeID = info.SendNodeID = nextNode.ID;
                            info.ReceiveNodeName = info.SendNodeName = nextNode.Name;
                            info.FormID = this.FormInfo.ID;
                            info.PreTaskID = this.TaskInfo.ID;
                            info.FromType = (int)FromType.结束;
                            info.SendID = AppSession.UserID;
                            info.SendName = AppSession.UserName;
                            info.ReadTime = info.FinishTime = info.SendTime = DateTime.Now;
                            info.ReceiveID = -100;//结束后不需要接收人
                            info.ReceiveName = "";
                            info.State = (int)TaskState.已完成;
                            info.Result = "";

                            Task.Save(info);
                            
                            

                        }                     

                    }
                }

               
                DbOper.CommitTrans();

                //跳转已办件列表
                int tabIndex = (int)DealtListTab.我经办的;
                if (this.FormInfo.CreatorID == AppSession.UserID)
                {
                    tabIndex = (int)DealtListTab.我起草的;
                }


                string script = "alert('提交成功');location.href='DealtList.aspx?TabIndex=" + tabIndex + "';";
                JSUtil.ResponseJS(script);
                //JSUtil.ExcuteJS(script);
            }
            catch (Exception ex)
            {
                DbOper.RollbackTrans();

                string script = "alert('发送失败:" + ex.Message.Replace("'", "").Replace("\"", "") + "');history.back();";
                JSUtil.ExcuteJS(script);
            }

        }

       
        /// <summary>
        /// 保存表单数据和修改任务状态
        /// </summary>
        private void SaveFormData(TaskState state)
        {
            //保存表单数据

            XElement fields = null;
            if (this.TaskInfo == null)
            {
                fields = XElement.Parse(this.FlowInfo.FormTemplate).Element(ElementItem.DataFields);
            }
            else
            {
                fields = XElement.Parse(this.FormInfo.FormData);
            }
            
            foreach (XElement field in fields.Elements())
            {
                if (Request.Form[field.Name.LocalName] != null)
                {
                    field.Value = Request.Form[field.Name.LocalName];//如果是checkbox 或 radio 不做选择的话也会为null或控件的disabled属性为真时也为null
                }
            }

            
            if (TaskFromType == FromType.新建)
            {
                if (this.TaskInfo == null)
                {
                    this.FormInfo.CreatorID = AppSession.UserID;
                    FormInfo.CreatorName = AppSession.UserName;
                    FormInfo.FlowID = int.Parse(FlowID);               
                    FormInfo.Name = _flow.GetInfo(FlowID).Name;//默认为流程名称
                    FormInfo.State = (int)FormState.流转中;
                    //FormInfo.TemplateID = this.TempInfo.ID;
                }

                FormInfo.InputTime = DateTime.Now;
            }
            FormInfo.FormData = fields.ToString();           
            FlowForm.Save(FormInfo);           

            if (this.TaskInfo == null)
            {
                //保存模板及流程
                FlowSnapBO snap = new FlowSnapBO(DbOper);
                this.FormInfo.SnapInfo = snap.Save(this.FlowInfo, FormInfo.ID);
            }

            //保存任务表
            if (this.TaskInfo == null)////有可能来自于草稿箱
            {
                this.TaskInfo = new FlowTaskInfo();

                this.TaskInfo.ID = Guid.NewGuid();
                this.TaskInfo.PreTaskID = null;
                this.TaskInfo.ReceiveNodeID = this.TaskInfo.SendNodeID = this.FlowInfo.StartNode.ID;
                this.TaskInfo.ReceiveNodeName = this.TaskInfo.SendNodeName = this.FlowInfo.StartNode.Name;
                this.TaskInfo.FinishTime = this.TaskInfo.ReadTime = this.TaskInfo.SendTime = DateTime.Now;
                this.TaskInfo.FlowID = int.Parse(FlowID);
                this.TaskInfo.FormID = FormInfo.ID;
                this.TaskInfo.ReceiveID = this.TaskInfo.SendID = AppSession.UserID;
                this.TaskInfo.ReceiveName = this.TaskInfo.SendName = AppSession.UserName;
                this.TaskInfo.Result = "";//新建是不需要审核意见的
                this.TaskInfo.State = (int)state;
                Task.Save(this.TaskInfo, true);
                Task.InitDelegate(this.TaskInfo);
            }
            else
            {
                this.TaskInfo.FinishTime = DateTime.Now;
                this.TaskInfo.Result = txtResult.Text;
                this.TaskInfo.State = (int)state;
                Task.Save(this.TaskInfo, false);
            }
        }

        //产生新的任务
        private void CreateNewTask(List<int> userIDs,int nextNodeID, FromType fromType)
        {
            XElement nodes = XElement.Parse(this.FormInfo.SnapInfo.Nodes);

            UserBO user = new UserBO();
            Dictionary<int, string> idNames = user.GetIDName(userIDs);
            foreach (int id in idNames.Keys)
            {
                FlowTaskInfo info = new FlowTaskInfo();
               
                info.FlowID = int.Parse(this.FlowID);
                info.ReceiveNodeID = nextNodeID;
                info.ReceiveNodeName = nodes.Elements().Where(ele => ele.Element("ID").Value == info.ReceiveNodeID.ToString()).First().Element("Name").Value;

                info.SendNodeID = this.TaskInfo.ReceiveNodeID;
                info.SendNodeName = this.TaskInfo.ReceiveNodeName;

                info.FormID = this.FormInfo.ID;
                info.PreTaskID = this.TaskInfo.ID;


                info.FromType = (int)fromType;
                info.SendID = AppSession.UserID;
                info.SendName = AppSession.UserName;
                info.SendTime = DateTime.Now;
                info.ReceiveID = id;
                if (idNames.ContainsKey(id))
                {
                    info.ReceiveName = idNames[id];
                }
                info.State = (int)TaskState.待处理;                

                Task.Save(info);

            }
        }
       

        //暂存
        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (this.TaskFromType == FromType.新建)
            {
                SaveFormData(TaskState.存草稿);
                string script = "alert('提交成功');location.href='DraftList.aspx';";
                JSUtil.ResponseJS(script);
            }
            else
            {
                SaveFormData(TaskState.待处理);
                string script = "alert('提交成功');location.href='RequiredList.aspx';";
                JSUtil.ResponseJS(script);
            }
        }

        protected void btnReturn_Click(object sender, EventArgs e)
        {
            try
            {
                this.DbOper.BeginTrans();
                SaveFormData(TaskState.已完成);

                int nextNodeID = this.TaskInfo.PreTaskInfo.ReceiveNodeInfo.ID;
                CreateNewTask(new List<int>() { this.TaskInfo.SendID }, nextNodeID, FromType.退回);

                DbOper.CommitTrans();

                //跳转已办件列表
                int tabIndex = (int)DealtListTab.我经办的;
                if (this.FormInfo.CreatorID == AppSession.UserID)
                {
                    tabIndex = (int)DealtListTab.我起草的;
                }
                string script = "alert('退回成功');location.href='DealtList.aspx?TabIndex=" + tabIndex + "';";
                JSUtil.ResponseJS(script);
            }
            catch (Exception ex)
            {
                DbOper.RollbackTrans();

                string script = "alert('退回失败:" + ex.Message.Replace("'", "").Replace("\"", "") + "');history.back();";
                JSUtil.ExcuteJS(script);
            }
        }
       
    }
}
